﻿using System;
using System.Collections.Generic;

namespace Viyi.Util.NameStyle
{
    public class NameStyleCollection
    {
        public static class StyleNames
        {
            public const string Pascal = "pascal";
            public const string Camel = "camel";
            public const string Underscore = "underscore";
            public const string Hyphen = "hyphen";
        }

        internal static class DefaultStyles
        {
            public static readonly IStyleConverter Pascal = new PascalStyleConverter();
            public static readonly IStyleConverter Camel = new PascalStyleConverter();
            public static readonly IStyleConverter Underscore = new UnderscoreStyleConverter();
            public static readonly IStyleConverter Hyphen = new HyphenStyleConverter();
        }

        private readonly Dictionary<string, IStyleConverter>
            data = new Dictionary<string, IStyleConverter>(StringComparer.OrdinalIgnoreCase)
            {
                {StyleNames.Pascal, DefaultStyles.Pascal},
                {StyleNames.Camel, DefaultStyles.Camel},
                {StyleNames.Underscore, DefaultStyles.Underscore},
                {StyleNames.Hyphen, DefaultStyles.Hyphen}
            };

        public NameStyleCollection Register(string name, IStyleConverter converter)
        {
            this[name] = converter;
            return this;
        }

        public IStyleConverter this[string styleName]
        {
            get
            {
                IStyleConverter converter;
                return data.TryGetValue(styleName, out converter) ? converter : null;
            }

            set
            {
                if (string.IsNullOrEmpty(styleName))
                {
                    throw new ArgumentNullException("styleName");
                }

                if (value == null)
                {
                    throw new ArgumentNullException("value");
                }

                data[styleName] = value;
            }
        }

        public IStyleConverter Default { get; set; }

        public IStyleConverter PascalStyle
        {
            get { return this[StyleNames.Pascal]; }
            set { this[StyleNames.Pascal] = value ?? DefaultStyles.Pascal; }
        }

        public IStyleConverter CamelStyle
        {
            get { return this[StyleNames.Camel]; }
            set { this[StyleNames.Pascal] = value ?? DefaultStyles.Camel; }
        }

        public IStyleConverter UnderscoreStyle
        {
            get { return this[StyleNames.Underscore]; }
            set { this[StyleNames.Underscore] = value ?? DefaultStyles.Underscore; }
        }

        public IStyleConverter HyphenStyle
        {
            get { return this[StyleNames.Hyphen]; }
            set { this[StyleNames.Hyphen] = value ?? DefaultStyles.Hyphen; }
        }
    }
}
